package cn.weiron.fun.infrastructure.dictionary;

import cn.weiron.fun.infrastructure.dictionary.repository.DictionaryRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>组件：字典缓存读取器。</p>
 * <p>组件初始化时载入全部字典数据到内存中，可以随时获取和对应</p>
 */
@Component("dictionaryCacheReader")
public class DictionaryCacheReader {
    /**
     * 载入全部
     */
    private static final Logger logger = LoggerFactory.getLogger(DictionaryCacheReader.class);

    /**
     * 字典仓储服务
     */
    private final DictionaryRepository repository;

    /**
     * 内存字典表
     */
    private final Map<DictionaryGroup, Map<String, Dictionary>> dictionaryMap;

    /**
     * 初始化
     */
    @PostConstruct
    public void refresh() {
        logger.info("Start load all data of the dictionary table!");
        List<Dictionary> dictionaries = repository.findAll();
        logger.info("Finish loading all dictionaries，size:" + dictionaries.size());
        if (dictionaries.isEmpty()) return;

        //对全部字典进行分组划分
        dictionaryMap.clear();
        for (Dictionary dictionary : dictionaries) {
            DictionaryGroup curGroup = dictionary.getGroup();
            Map<String, Dictionary> curGroupMap = dictionaryMap.getOrDefault(curGroup, new HashMap<>());
            curGroupMap.put(dictionary.getCode(), dictionary);
            dictionaryMap.put(curGroup, curGroupMap);
        }
        logger.info("Finish loading all dictionaries transform.");
    }

    /**
     * 检查指定键是否存在
     */
    public boolean contains(String code){
        return dictionaryMap.values().stream()
                .anyMatch(map->map.containsKey(code));
    }

    /**
     * 获取指定code对应的字典信息
     */
    public Optional<Dictionary> get(String code) {
        return dictionaryMap.values().stream()
                .filter(map -> map.containsKey(code))
                .findFirst()
                .map(map -> Dictionary.copy(map.get(code)));
    }

    /**
     * 获取指定code对应的显示标签
     */
    public Optional<String> getLabel(String code) {
        return get(code).map(Dictionary::getLabel);
    }

    /**
     * 获取指定分类下的全部字典
     *
     * @param group 分类标识
     */
    public List<Dictionary> dictionaries(DictionaryGroup group) {
        return dictionaryMap.getOrDefault(group, new HashMap<>())
                .values().stream()
                .sorted(Comparator.comparing(Dictionary::getCode, Comparator.naturalOrder()))
                .collect(Collectors.toList());
    }

    /**
     * 获取全部字典
     */
    public Map<DictionaryGroup,List<Dictionary>> dictionariesMap(){
        Map<DictionaryGroup,List<Dictionary>> result=new HashMap<>();
        for (DictionaryGroup dictionaryGroup : dictionaryMap.keySet()) {
            result.put(dictionaryGroup,dictionaries(dictionaryGroup));
        }
        return result;
    }

    public DictionaryCacheReader(
            @Qualifier("dictionaryRepositoryMysql") DictionaryRepository repository
    ) {
        this.repository = repository;
        this.dictionaryMap = new HashMap<>();
    }
}